from typing import Optional, List
from pydantic import BaseModel, Field, validator
from datetime import datetime
from app.shared.constants.enums import DeviceStatus, DeviceType


class DeviceBase(BaseModel):
    """设备基础信息"""
    device_name: str = Field(..., min_length=1, max_length=100, description="设备名称")
    device_type: DeviceType = Field(..., description="设备类型")
    location_name: Optional[str] = Field(None, max_length=100, description="位置名称")
    latitude: Optional[float] = Field(None, ge=-90, le=90, description="纬度")
    longitude: Optional[float] = Field(None, ge=-180, le=180, description="经度")


class DeviceCreate(DeviceBase):
    """创建设备"""
    device_code: str = Field(..., min_length=3, max_length=50, description="设备编码")
    
    @validator('device_code')
    def validate_device_code(cls, v):
        # 设备编码只能包含字母、数字和下划线
        if not v.replace('_', '').isalnum():
            raise ValueError('设备编码只能包含字母、数字和下划线')
        return v.upper()


class DeviceUpdate(BaseModel):
    """更新设备信息"""
    device_name: Optional[str] = Field(None, min_length=1, max_length=100, description="设备名称")
    location_name: Optional[str] = Field(None, max_length=100, description="位置名称")
    latitude: Optional[float] = Field(None, ge=-90, le=90, description="纬度")
    longitude: Optional[float] = Field(None, ge=-180, le=180, description="经度")
    firmware_version: Optional[str] = Field(None, description="固件版本")
    hardware_version: Optional[str] = Field(None, description="硬件版本")


class DeviceStatusUpdate(BaseModel):
    """设备状态更新"""
    status: DeviceStatus = Field(..., description="设备状态")
    materials_level: Optional[int] = Field(None, ge=0, le=100, description="耗材余量百分比")


class DeviceResponse(DeviceBase):
    """设备响应信息"""
    id: int = Field(..., description="设备ID")
    device_code: str = Field(..., description="设备编码")
    status: DeviceStatus = Field(..., description="设备状态")
    materials_level: Optional[int] = Field(None, description="耗材余量")
    last_maintenance_at: Optional[datetime] = Field(None, description="最后维护时间")
    next_maintenance_at: Optional[datetime] = Field(None, description="下次维护时间")
    last_seen_at: Optional[datetime] = Field(None, description="最后在线时间")
    firmware_version: Optional[str] = Field(None, description="固件版本")
    hardware_version: Optional[str] = Field(None, description="硬件版本")
    install_date: Optional[datetime] = Field(None, description="安装日期")
    warranty_date: Optional[datetime] = Field(None, description="保修日期")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    
    class Config:
        from_attributes = True


class DeviceDetailResponse(DeviceResponse):
    """设备详细信息响应"""
    work_orders_count: Optional[int] = Field(None, description="关联工单数量")
    alerts_count: Optional[int] = Field(None, description="未解决告警数量")
    recent_sensor_data: Optional[List[dict]] = Field(None, description="最近传感器数据")


class DeviceListQuery(BaseModel):
    """设备列表查询"""
    page: int = Field(1, ge=1, description="页码")
    page_size: int = Field(20, ge=1, le=100, description="每页数量")
    search: Optional[str] = Field(None, description="搜索关键词")
    device_type: Optional[DeviceType] = Field(None, description="设备类型筛选")
    status: Optional[DeviceStatus] = Field(None, description="设备状态筛选")
    location: Optional[str] = Field(None, description="位置筛选")
    materials_level_lt: Optional[int] = Field(None, ge=0, le=100, description="耗材余量小于")
    sort_by: Optional[str] = Field("updated_at", description="排序字段")
    sort_order: Optional[str] = Field("desc", regex=r'^(asc|desc)$', description="排序方向")


class DeviceControlCommand(BaseModel):
    """设备控制指令"""
    command_type: str = Field(..., description="指令类型")
    action: str = Field(..., description="动作")
    params: Optional[dict] = Field(None, description="参数")


class DeviceControlRequest(BaseModel):
    """设备控制请求"""
    commands: List[DeviceControlCommand] = Field(..., description="控制指令列表")
    operator: Optional[str] = Field(None, description="操作员")


class SensorDataResponse(BaseModel):
    """传感器数据响应"""
    id: int = Field(..., description="数据ID")
    device_id: int = Field(..., description="设备ID")
    timestamp: datetime = Field(..., description="时间戳")
    data_type: str = Field(..., description="传感器类型")
    value: float = Field(..., description="传感器值")
    unit: Optional[str] = Field(None, description="单位")
    quality: int = Field(..., description="数据质量")
    created_at: datetime = Field(..., description="创建时间")
    
    class Config:
        from_attributes = True


class SensorDataQuery(BaseModel):
    """传感器数据查询"""
    device_id: int = Field(..., description="设备ID")
    data_type: Optional[str] = Field(None, description="传感器类型")
    start_time: Optional[datetime] = Field(None, description="开始时间")
    end_time: Optional[datetime] = Field(None, description="结束时间")
    page: int = Field(1, ge=1, description="页码")
    page_size: int = Field(100, ge=1, le=1000, description="每页数量")


class DeviceStatisticsResponse(BaseModel):
    """设备统计响应"""
    device_id: int = Field(..., description="设备ID")
    date: datetime = Field(..., description="统计日期")
    usage_count: int = Field(..., description="使用次数")
    usage_duration: int = Field(..., description="使用时长(分钟)")
    maintenance_count: int = Field(..., description="维护次数")
    fault_count: int = Field(..., description="故障次数")
    avg_materials_level: Optional[float] = Field(None, description="平均耗材余量")
    created_at: datetime = Field(..., description="创建时间")
    
    class Config:
        from_attributes = True


class DeviceMaintenanceRecord(BaseModel):
    """设备维护记录"""
    device_id: int = Field(..., description="设备ID")
    maintenance_type: str = Field(..., description="维护类型")
    description: str = Field(..., description="维护描述")
    parts_replaced: Optional[List[str]] = Field(None, description="更换部件")
    maintenance_duration: Optional[int] = Field(None, description="维护时长(分钟)")
    cost: Optional[float] = Field(None, description="维护成本")
    technician: str = Field(..., description="维护技师")
    notes: Optional[str] = Field(None, description="备注")


class DeviceBatchOperation(BaseModel):
    """设备批量操作"""
    device_ids: List[int] = Field(..., min_items=1, description="设备ID列表")
    operation: str = Field(..., description="操作类型")
    params: Optional[dict] = Field(None, description="操作参数")